
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
resource.AddFile( "materials/vgui/entities/prop_EasyEngine2.vtf" )
resource.AddFile( "materials/vgui/entities/prop_EasyEngine2.vmt" )
include('shared.lua')
----------variables------------
-----------TURBO  (don't ask me why the variables are called nos)
ENT.NosConnected = 0
ENT.MoveTheModel = 0
ENT.NosValid = NULL
ENT.NosConMessage = 0
ENT.NosNotConMessage = 0
ENT.NosIsUsed = 0
----------TURBO

-----------EXAUST
ENT.ExaustConnected = 0
ENT.ExaustValid = NULL
ENT.ExaustPhys = NULL
-----------EXAUST

-----------VEHICLE
ENT.VehicleConnected = 0
ENT.VehicleValid = NULL
ENT.VehiclePhys = NULL
-----------VEHICLE

-----------FUEL
ENT.FuelValid = NULL
ENT.MakeStopSound = 0
-----------FUEL

-----------RADIATOR
ENT.RadiatorConnected = 0
ENT.RadiatorValid = NULL
ENT.RadiatorPhys = NULL
-----------RADIATOR

-----------CAR HORN
ENT.CarHornConnected = 0
ENT.CarHornValid = NULL
-----------CAR HORN
-----------Misc
ENT.Force = 1
ENT.OnOrOff = 0

ENT.ForSound = 0
ENT.BackSound = 0
ENT.Fuel = 500
ENT.MaxFuel = 500
ENT.FuelTankEnt = NULL
ENT.EngineHeat = 255
ENT.EngineDestroyed = 0
ENT.HornDelay = CurTime()
-----------Misc end
----Sounds
 ENT.FirstGear = NULL 
 ENT.ReverseGear = NULL
 ENT.TomGang = NULL
 ENT.NOS = NULL
 ENT.EngineOff = NULL
 ENT.EngineOverheat = NULL
 ENT.FuelingUp = NULL
 ENT.FuelingReady = NULL

 ENT.FirstGearOnce = 0 
 ENT.FirstGearLoopOnce = 0 
 ENT.ReverseGearOnce = 0
 ENT.TomGangOnce = 0
 ENT.NosOnce = 0
 ENT.EngineOffOnce = 0

------------------------------------VARIABLES END
function ENT:SpawnFunction( ply, tr )
--------Spawning the entity and getting some sounds i use.   
 	if ( !tr.Hit ) then return end 
 	 
 	local SpawnPos = tr.HitPos + tr.HitNormal * 10 
 	 
 	local ent = ents.Create( "sent_EasyEngine" )
	ent:SetPos( SpawnPos ) 
 	ent:Spawn()
 	ent:Activate() 
 	ent.Owner = ply
	return ent 
 	 
end

function ENT:Initialize()

	self.Entity:SetModel("models/vehicle/vehicle_engine_block.mdl")
	self.Entity:SetColor(255, 255, 255, 255)
	self.Entity:SetOwner(self.Owner)
	self.Entity:PhysicsInit(SOLID_VPHYSICS)
	self.Entity:SetMoveType(MOVETYPE_VPHYSICS)
	self.Entity:SetSolid(SOLID_VPHYSICS)

	self.Entity:SetSolid(SOLID_VPHYSICS)	
    local phys = self.Entity:GetPhysicsObject()
	if(phys:IsValid()) then phys:Wake() end


 self.FirstGear = CreateSound(self.Entity,"vehicles/v8/v8_firstgear_rev_loop1.wav") 
 self.ReverseGear = CreateSound(self.Entity,"vehicles/v8/fourth_cruise_loop2.wav") 
 self.TomGang = CreateSound(self.Entity,"vehicles/v8/v8_idle_loop1.wav")
 self.NOS = CreateSound(self.Entity,"vehicles/v8/v8_turbo_on_loop1.wav")
 self.EngineOff = CreateSound(self.Entity,"vehicles/v8/v8_stop1.wav")
 self.EngineOverheat = CreateSound(self.Entity,"vehicles/digger_grinder_stop1.wav")
 self.FuelingUp = CreateSound(self.Entity,"ambient/water/leak_1.wav")
 self.FuelingReady = CreateSound(self.Entity,"buttons/button10.wav")

end

-------------------------------------------PHYS COLLIDE
function ENT:PhysicsCollide( data, phys ) 
	ent = data.HitEntity
--OK so here is how it works, if the right model collides with the motor then something will happen.
--------TURBO MODEL
			if string.find(ent:GetModel(), "models/props_c17/grinderclamp01a.mdl") and self.NosConnected == 0 then
			self.NosValid = ent
			self.NosConnected = 1
			self.MoveTheModel = 1
			self.Entity:EmitSound("buttons/lever1.wav", 100, 100)
			end
---------------
--------VEHICLE
			if string.find(ent:GetClass(), "vehicle*") and self.VehicleConnected == 0 then
			self.VehicleValid = ent
			self.VehicleConnected = 1
			self.VehicleValid.ConnectedEngine = self.Entity
			self.Entity:EmitSound("buttons/lever1.wav", 100, 100)
			constraint.Elastic( self.Entity, self.VehicleValid, 0, 0, Vector( 0, 0, 0 ) , Vector( 0, 0, 0 ) , 0, 0, 0, "cable/cable2", 3, 0 )
			end
---------------
--------FUEL TANK MODEL
			if string.find(ent:GetModel(), "models/props_junk/metalgascan.mdl") and self.MaxFuel == 500 then
			self.Entity:EmitSound("buttons/lever1.wav", 100, 100)
			self.MaxFuel = 5000
			self.FuelTankEnt = ent
			constraint.Elastic( self.Entity, self.FuelTankEnt, 0, 0, Vector( 0, 0, 0 ) , Vector( 0, -6, 8 ) , 0, 0, 0, "cable/cable2", 3, 0 )
			end
---------------
--------EXAUST MODEL
--Putting on a elastic constraint was quite hard since i wanted the elastic to be placed on the end of the exaust pipe
--I tested a few coordinates and found that Vector( -26, 9, 0 )was the end of the exaust.
			if string.find(ent:GetModel(), "models/props_vehicles/carparts_muffler01a.mdl") and self.ExaustConnected == 0 then
			self.ExaustValid = ent
			self.ExaustConnected = 1
			self.ExaustPhys = ent:GetPhysicsObject()
			constraint.Elastic( self.Entity, self.ExaustValid, 0, 0, Vector( 0, 0, 0 ) , Vector( -26, 9, 0 ) , 0, 0, 0, "cable/cable2", 3, 0 )
			self.Entity:EmitSound("buttons/lever1.wav", 100, 100)
			end
---------------
--------RADIATOR MODEL
			if string.find(ent:GetModel(), "models/props_wasteland/prison_heater002a.mdl") and self.RadiatorConnected == 0 then
			self.RadiatorValid = ent
			self.RadiatorConnected = 1
			self.RadiatorPhys = ent:GetPhysicsObject()
			constraint.Elastic( self.Entity, self.RadiatorValid, 0, 0, Vector( 0, 0, 0 ) , Vector( 0, 0, 0 ) , 0, 0, 0, "cable/cable2", 3, 0 )
			self.Entity:EmitSound("buttons/lever1.wav", 100, 100)
			end
---------------
--------CAR HORN MODEL
			if string.find(ent:GetModel(), "models/props_junk/garbage_metalcan002a.mdl") and self.CarHornConnected == 0 then
			self.CarHornValid = ent
			self.CarHornConnected = 1
			constraint.Elastic( self.Entity, self.CarHornValid, 0, 0, Vector( 0, 0, 0 ) , Vector( 0, 0, 0 ) , 0, 0, 0, "cable/cable2", 2, 0 )
			self.Entity:EmitSound("buttons/lever1.wav", 100, 100)
			end
---------------
--------REFUELING
--If the gascan hits the engine ent then it will refuel.
			if string.find(ent:GetModel(), "models/props_junk/gascan001a.mdl") and self.Fuel < self.MaxFuel then
			self.Fuel = self.Fuel + 20
			self.Entity:EmitSound("ambient/water/water_spray1.wav", 100, 100)
			if self.Fuel >= self.MaxFuel then
			self.Entity:EmitSound("buttons/button10.wav", 100, 100)
			self.Fuel = self.MaxFuel
			end
			end
---------------
--------REFUELING2
--If the model that's roped with the gaspump touches the engine it will refuel instantly.
			if string.find(ent:GetModel(), "models/props_wasteland/prison_pipefaucet001a.mdl") and self.Fuel < self.MaxFuel then
			self.Fuel = self.Fuel + 5000
			self.FuelValid = ent
			self.Entity:EmitSound("ambient/water/rain_drip2.wav", 100, 100)
			if self.Fuel >= self.MaxFuel then
			self.Entity:EmitSound("buttons/button10.wav", 100, 100)
			self.Fuel = self.MaxFuel
			end
			end
---------------
--------REPAIRING
--The wrench repairs the engine if it's destroyed.
			if string.find(ent:GetModel(), "models/props_c17/tools_wrench01a.mdl") and self.EngineDestroyed == 1 then
			self.EngineDestroyed = 0
			self.Entity:EmitSound("buttons/lever3.wav", 100, 100)
			end
---------------
--------TUNEING UP
--Tune up just increases the force multiplier
			if string.find(ent:GetModel(), "models/props_c17/tools_pliers01a.mdl") then
			self.Force = self.Force + 0.1
			if self.Force > 2.50 then
			self.Force = 2.50
			end
			self.Entity:EmitSound("vehicles/v8/v8_stop1.wav", 100, self.Force*100)
			end	
---------------
--------TUNEING DOWN
--Tune down just decreases the force multiplier
		if string.find(ent:GetModel(), "models/props_c17/TrapPropeller_Lever.mdl") then
		self.Force = self.Force - 0.1
		if self.Force < 0.1 then
		self.Force = 0.1
	 	end
			self.Entity:EmitSound("vehicles/v8/v8_stop1.wav", 100, self.Force*100)
		end
-----------
end
-------------------------------------------DRAW

-------------------------------------------THINK
function ENT:Think()

--If the engine gets under water i will stop
if self.Entity:WaterLevel() > 0 then
self.OnOrOff = 0
end

--If the turbo model collides with the engine the "MoveTheModel" variable will be changed to 1.
--The Turbo model will be no collided with everything except the world and it will be welded to the engine.
if self.MoveTheModel == 1 then
self.MoveTheModel = 0
	constraint.NoCollide( self.Entity, self.NosValid, 0, 0 )
		local Position = self.Entity:GetPos()+((self.Entity:GetForward()*5)+(self.Entity:GetUp()*8))
				self.NosValid:SetPos(Position)
					local EntAng = self.Entity:GetAngles()
				self.NosValid:SetAngles(EntAng)
			constraint.Weld( self.Entity, self.NosValid, 0, 0, 0)
		self.NosValid:SetCollisionGroup( COLLISION_GROUP_WORLD )
	self.NosValid.CollisionGroup = COLLISION_GROUP_WORLD
end

--If the radiator is connected then the engine will be cooled down by 5 units
if self.RadiatorConnected == 1 then
self.EngineHeat = self.EngineHeat + 5
end

--If the radiator is connected then the engine will be cooled down by 1 unit
if self.RadiatorConnected == 0 then
self.EngineHeat = self.EngineHeat + 1
end

--The cools maximum value should be 255 since i use that value to change the colour of the engine.
if self.EngineHeat > 255 then
self.EngineHeat = 255
end

--If the cool is less then 0 then it's overheated and the engine will stop or it will be destroyed.
if self.EngineHeat < 0 then
	self.EngineOverheat:Stop()
	self.EngineHeat = 0
	self.OnOrOff = 0
	self.EngineOverheat:Play()

	local IsDestroyed = math.random( 1, 2)
		if IsDestroyed == 1 then
		self.EngineDestroyed = 1
		end
end
	
	self.Entity:SetColor(255, self.EngineHeat, self.EngineHeat, 255)

--If the engine is destroyed then the colour will be black.
if self.EngineDestroyed == 1 then
self.OnOrOff = 0
self.Entity:SetColor(50, 50, 50, 255)
end

------------Engine Effects
--OverHeated
--If the engine is starting to overheat then it will emit white steamy smoke.
if self.EngineHeat < 100 then
		local effectdata = EffectData()
		effectdata:SetOrigin( self.Entity:GetPos() ) 
		util.Effect( "EngineSteamSmoke", effectdata )
end

--If the engine is destroyed then it will emit black smoke
if self.EngineDestroyed == 1 then
		local effectdata = EffectData()
		effectdata:SetOrigin( self.Entity:GetPos() ) 
		util.Effect( "EngineBlackSmoke", effectdata )
end


-----------CHECKING CONNECTED DEVICES

--Checking if the car horn is connected
if not (self.CarHornValid:IsValid()) then
self.CarHornConnected = 0
end

--Checking if the turbo is connected
if not (self.NosValid:IsValid()) then
self.NosConnected = 0
end

--Checking if the fueltank is connected
--if it's not then the maximum fuel will be changed
if not (self.FuelTankEnt:IsValid()) then
self.MaxFuel = 500
	if self.Fuel > 500 then
	self.Fuel = 500
	end
end

--Checking if the vehicle is connected
if not (self.VehicleValid:IsValid()) then 
	self.VehicleConnected = 0
end


--Checking if the exaust is connected
if not (self.ExaustValid:IsValid()) then
self.ExaustConnected = 0
end

--Checking if the radiator is connected
if not (self.RadiatorValid:IsValid()) then
self.RadiatorConnected = 0
end

--------------------CHECK IF THE BUTTONS AREN'T PRESSED
--Just resetting some values if the buttons aren't pressed
if self.Entity.Owner:InVehicle() and not ( self.Entity.Owner:KeyDown( IN_SPEED ) ) then
self.NosIsUsed = 0
self.NosOnce = 0
self.NOS:Stop()
self.NOSSound = 0
self.ForSound = 1
self.FirstGear:Play()
end
-------
if not ( self.Entity.Owner:KeyDown( IN_FORWARD ) ) then
self.ForSound = 0
self.FirstGearOnce = 0
self.NOS:Stop()
self.NosOnce = 0
 self.FirstGear:Stop()
end
-------
if not ( self.Entity.Owner:KeyDown( IN_BACK ) ) then
self.BackSound = 0
self.ReverseGearOnce = 0
self.ReverseGear:Stop() 
end


if ( self.Entity.Owner:KeyDown( IN_SPEED ) ) and not ( self.Entity.Owner:KeyDown( IN_FORWARD ) ) then 
self.NOSSound = 0
end
--------------------
--------------------IF THE ENGINE IS ON
--------------------MAKE SOUNDS

--If the engine isn't on some sounds will stop
---TomGang
if self.OnOrOff == 0 then
 self.TomGang:Stop()
    self.FirstGear:Stop()
	self.ReverseGear:Stop()
	self.NOS:Stop()
	self.TomGangOnce = 0
end


--Checkign if the player is in the right vehicle
if self.VehicleConnected == 0 or not (self.Entity.Owner:InVehicle()) then
self.OnOrOff = 0
end


--If the engine is on
if self.OnOrOff == 1 then

self.Fuel = self.Fuel - 1

--If the exaust isn't connected the exausts will come straight out from the engine
--I don't use SetStart to "set the start" but to send which direction the smoke should go
--I guess i'm not supposed to use SetStart like that but it works.
if 	self.ExaustConnected == 0 then
	local DirVec = self.Entity:GetUp()
		local effectdata = EffectData()
		effectdata:SetOrigin( self.Entity:GetPos() ) 
		effectdata:SetStart(DirVec) 
		util.Effect( "ExaustSmoke", effectdata )
end

--If the exaustpipe/muffler is connected then the smoke will come out from it instead form the engine.
if 	self.ExaustConnected == 1 then
	local DirVec = self.ExaustValid:GetForward()
	local MoveRight = self.ExaustValid:GetRight()
	
		local effectdata = EffectData()
		effectdata:SetOrigin( self.ExaustValid:GetPos()+(DirVec*25)+(MoveRight*4)) 
		effectdata:SetStart(DirVec) 
		util.Effect( "ExaustSmokeTomGang", effectdata )
end

--If the forward sound and the back sound aren't played the TomGang sound should be played. 
if self.ForSound == 0 and self.BackSound == 0 and self.TomGangOnce == 0 then
	self.TomGangOnce = 1
	self.TomGang:Play()
end
---
---Forward Sound
if self.ForSound == 1 and  self.FirstGearOnce == 0 and self.NOSSound == 0 then 
	self.TomGang:Stop()
	self.FirstGearOnce = 1
    self.FirstGear:Play()
end
---
---Turbo sound
if self.NOSSound == 1 and self.NosOnce == 0 then
	self.TomGang:Stop()
	self.FirstGear:Stop()
	self.NosOnce = 1
	self.NOS:Play()
end
---
---Backward Sound
if self.BackSound == 1 and self.ReverseGearOnce == 0 and self.NOSSound == 0 then
	self.TomGang:Stop()
	self.ReverseGearOnce = 1
	self.ReverseGear:Play()
end
---

--------------------
--Checking if the buttons are pressed
--------------------CAR HORN
if self.Entity.Owner:KeyDown( IN_ATTACK ) and self.CarHornConnected == 1 and self.HornDelay < CurTime() then
			self.CarHornValid:EmitSound("Easy_Engine_Sounds/GeneralLeeCarHorn.wav", 100, 100)
self.HornDelay = CurTime()+3
end
--------------------
--------------------FORWARD
if self.Entity.Owner:KeyDown( IN_FORWARD ) and self.BackSound == 0 then

self.Fuel = self.Fuel - 3
	 self.TomGangOnce = 0
	local forward = self.Entity:GetForward()
		local speed = self.Entity:GetPhysicsObject():GetVelocity()
			self.Entity:GetPhysicsObject():SetVelocity(((forward*2000)*self.Force)+speed)
		self.ForSound = 1

if 	self.ExaustConnected == 1 then
	local DirVec = self.ExaustValid:GetForward()
	local MoveRight = self.ExaustValid:GetRight()
	
		local effectdata = EffectData()
		effectdata:SetOrigin( self.ExaustValid:GetPos()+(DirVec*25)+(MoveRight*4) )
		effectdata:SetStart(DirVec*2) 
		util.Effect( "ExaustSmoke", effectdata )

end

end
--------------------
--------------------TURBO
if( self.Entity.Owner:KeyDown( IN_SPEED ) and self.BackSound == 0 and self.ForSound == 1 and self.NosConnected == 1 ) then
self.EngineHeat = self.EngineHeat - 8
self.Fuel = self.Fuel - 5
self.NosIsUsed = 1


	self.TomGangOnce = 0
	local forward = self.Entity:GetForward()
	local physNOS = self.Entity:GetPhysicsObject()
	physNOS:ApplyForceCenter(((self.NosValid:GetForward())*(5000*self.Force)))
	physNOS:ApplyForceCenter(((self.Entity:GetForward())*(5000*self.Force)))

		local speed = self.NosValid:GetPhysicsObject():GetVelocity()
		self.NosValid:GetPhysicsObject():SetVelocity(((forward*5000)*self.Force)+speed)

	self.NOSSound = 1

if 	self.ExaustConnected == 1 then
	local DirVec = self.ExaustValid:GetForward()
	local MoveRight = self.ExaustValid:GetRight()
	
		local effectdata = EffectData()
		effectdata:SetOrigin( self.ExaustValid:GetPos()+(DirVec*25)+(MoveRight*4) )
		effectdata:SetStart(DirVec*2) 
		util.Effect( "ExaustSmoke", effectdata )

end

end
--------------------
--------------------BACK
if self.Entity.Owner:KeyDown( IN_BACK ) and self.ForSound == 0 and self.NosIsUsed == 0 then

self.Fuel = self.Fuel - 3
	 self.TomGangOnce = 0
	local forward = self.Entity:GetForward()

		local speed = self.Entity:GetPhysicsObject():GetVelocity()
			self.Entity:GetPhysicsObject():SetVelocity(((forward*-1000)*self.Force)+speed)

self.BackSound = 1
end
--------------------
--------------------RIGHT
if self.Entity.Owner:KeyDown( IN_MOVERIGHT ) then
	local phys = self.Entity:GetPhysicsObject()
		phys:AddAngleVelocity(Vector(0,0,-10000)*self.Force)
end
--------------------
--------------------LEFT
if self.Entity.Owner:KeyDown( IN_MOVELEFT) then
	local phys = self.Entity:GetPhysicsObject()
		phys:AddAngleVelocity(Vector(0,0,10000)*self.Force)
end
----------------------
end
--------------------IF THE ENGINE IS ON END
--------------------ENGINE MOVEMENT
--This code will make the engine move in a randome direction if it's on.
--It makes the engine shake.
if self.OnOrOff == 1 then
local phys = self.Entity:GetPhysicsObject()
phys:ApplyForceCenter( Vector(math.Rand(-1,1), math.Rand(-1,1), math.Rand(-1,1))*(self.Force*5000))
end
--------------------
--------------------TOGGLE ENGINE ON AND OFF
--If you press both walk and duck the engine should start
if (self.Entity.Owner:KeyDown( IN_JUMP ) ) and self.VehicleConnected == 1 then
if self.Entity.Owner:GetVehicle() == self.VehicleValid then


		self.OnOrOff = self.OnOrOff + 1
		
			if self.OnOrOff > 1 then 
			self.OnOrOff = 0 
			self.DoItOnce = 0
			end
end
end

if self.OnOrOff == 1 then
self.EngineOffOnce = 0
end

if self.Fuel < 0 then
self.OnOrOff = 0
end

if self.OnOrOff == 0 and self.EngineOffOnce == 0 then
 self.EngineOff:Stop()
 self.EngineOff:Play()
 self.EngineOffOnce = 1
end
--------------------
--------------------
end
--------------------

--This function will stop all sounds if the engine is removed
--Why? because the sounds will stay if i don't even if the engine is removed. 
function ENT:OnRemove()
 self.FirstGear:Stop()
 self.ReverseGear:Stop()
 self.TomGang:Stop()
 self.NOS:Stop()
 self.EngineOff:Stop()
 self.EngineOverheat:Stop()
 self.FuelingUp:Stop()
 self.FuelingReady:Stop()

--If the engine is removed and the turbo is connected it will remove it aswell.
--The turbo is nocollided so you couldn't connect it to another engine anyway.
if self.NosConnected == 1 then
self.NosValid:Remove()
end
end
